package com.chengqs.dfs.client;

import com.chengqs.dfs.namenode.rpc.model.MkdirRequest;
import com.chengqs.dfs.namenode.rpc.model.MkdirResponse;
import com.chengqs.dfs.namenode.rpc.model.ShutdownRequest;
import com.chengqs.dfs.namenode.rpc.model.ShutdownResponse;
import com.chengqs.dfs.namenode.rpc.service.NameNodeServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.netty.NegotiationType;
import io.grpc.netty.NettyChannelBuilder;
import lombok.extern.slf4j.Slf4j;

/**
 * <B>主类名称：</B>FileSystemImpl<BR>
 * <B>概要说明：</B>文件系统客户端的实现类<BR>
 *
 * @author: chengqs
 * @create: 2025-03-30 22:47:02
 **/
@Slf4j
public class FileSystemImpl implements FileSystem {

    private static final String NAME_NODE_HOSTNAME = "localhost";
    private static final int NAME_NODE_PORT = 50070;

    private final NameNodeServiceGrpc.NameNodeServiceBlockingStub nameNode;

    public FileSystemImpl() {
        ManagedChannel channel = NettyChannelBuilder
                .forAddress(NAME_NODE_HOSTNAME, NAME_NODE_PORT)
                .negotiationType(NegotiationType.PLAINTEXT)
                .build();
        this.nameNode = NameNodeServiceGrpc.newBlockingStub(channel);
    }

    /**
     * 创建目录
     * @param path 目录对应的路径
     * @throws Exception
     */
    @Override
    public void mkdir(String path) throws Exception {
        MkdirRequest request = MkdirRequest.newBuilder()
                .setPath(path)
                .build();
        MkdirResponse response = nameNode.mkdir(request);

        log.info("创建目录的响应：{}", response.getStatus());
    }

    @Override
    public void shutdown() throws Exception {
        ShutdownRequest request = ShutdownRequest.newBuilder()
                .setCode(1)
                .build();
        ShutdownResponse response = nameNode.shutdown(request);

        log.info("关闭namenode的响应：{}", response.getStatus());
    }

    @Override
    public void upload(byte[] file, String filename) throws Exception {
        // 必须先用filename发送一个RPC接口调用到master节点
        // 去尝试在文件目录树里创建一个文件
        // 此时还需要进行查重，如果这个文件已经存在，就不让你上传了

        // 就是找master节点去要多个数据节点的地址

        // 就是你要考虑自己上传几个副本，找对应副本数量的数据节点的地址
        // 尽可能在分配数据节点的时候，保证每个数据节点放的数据量是比较均衡的
        // 保证集群里各个机器上放的数据比较均衡

        // 依次把文件的副本上传到各个数据节点上去
        // 还要考虑到，如果上传的过程中，某个数据节点他上传失败
        // 此时你需要一个容错机制的考量
    }
}
